package myapp.Chat;

import java.util.ArrayList;

import myapp.DTO.UserDTO;
import myapp.EnumAndConstans.Constants;
import myapp.googlemap.R;
import myapp.helper.Utils;
import myapp.services.ChatServiceHelper;

import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.filter.MessageTypeFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;

import staticClass.XmppConnection;

import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

public class XmppClient extends Activity {
	private ArrayList<String> messages = new ArrayList<String>();
	private Handler mHandler;
	private SettingsDialog settingDialog;
	private FriendListDialog friendListDlg;
	private RequesterListDialog requesterListDlg;
	private AddFriendDialog addFriendDialog;
	
	
	private Button btnSetup;
	private Button btnSendMsg;
	private Button btnRecipient;
	private Button btnYourRequest;
	
	private EditText mRecipient;
	private EditText mSendText;
	private ListView mList;
	//private XMPPConnection connection;
	
	private UserDTO recipient;	
	private String userName;	//will be assign at SetNameToSettingButton

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.i("XMPPClient", "onCreate called");
		setContentView(R.layout.chat_activity_xmpp_client);

		initializeControlsAndHandlers();
		SetListenerForButtons();
		
		if (!XmppConnection.isConnected()){
			btnSetup.performClick();	//Sign in before chat
		}
		else{
			ProcessUserConnected();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_xmpp_client, menu);
		
		MenuItem autoUpdatingLocation = menu.findItem(R.id.xmpp_client_menu_auto_update_location);
		if (autoUpdatingLocation == null){
			Log.e("XmppClient", "[onCreateOptionsMenu] autoUpdatingLocation is null");
		}
		if (XmppConnection.isAutoUpdatingYourLocation)
			autoUpdatingLocation.setTitle(R.string.xmpp_client_menu_auto_update_on);
		else
			autoUpdatingLocation.setTitle(R.string.xmpp_client_menu_auto_update_off);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.xmpp_client_menu_auto_update_location:
			if (!XmppConnection.isAutoUpdatingYourLocation){
				XmppConnection.startAutoUpdating();
				item.setTitle(R.string.xmpp_client_menu_auto_update_on);
			}
			else{
				XmppConnection.stopAutoUpdating();
				item.setTitle(R.string.xmpp_client_menu_auto_update_off);
			}
			
			//staticClass.XmppConnection.updateUserLocation();
			break;
		case R.id.xmpp_client_menu_log_out:
			if (XmppConnection.isAutoUpdatingYourLocation)
				XmppConnection.stopAutoUpdating();
			
			if (XmppConnection.isConnected()){
				Log.i("XmppClient", "Log out start.");
				XmppConnection.LogOutAndCloseConnection();
				btnSetup.setText(R.string.xmpp_client_btn_Setup);
			}
			break;
			
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	private void initializeControlsAndHandlers(){
		mRecipient = (EditText) findViewById(R.id.recipient);
		mSendText = (EditText) findViewById(R.id.sendText);
		mList = (ListView) findViewById(R.id.listMessages);
		setListAdapter();

		// Dialog for getting the xmpp settings
		settingDialog = new SettingsDialog(this);
		friendListDlg = new FriendListDialog(this);
		requesterListDlg = new RequesterListDialog(this);
		addFriendDialog = new AddFriendDialog(this);
		
		btnRecipient = (Button) findViewById(R.id.btnRecipient);
		btnSendMsg = (Button) findViewById(R.id.send);
		btnSetup = (Button) this.findViewById(R.id.setup);
		btnYourRequest = (Button) findViewById(R.id.btnYourRequest);
		
		mHandler = new Handler();
	}
	
	private void SetListenerForButtons() {
		// Set a listener to show setting dialog
		btnSetup.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				OnDismissListener listener = new OnDismissListener() {					
					@Override
					public void onDismiss(DialogInterface dialog) {
						processDismissSettingDialog();
					}
				};
				
				settingDialog.setOnDismissListener(listener);
				
				mHandler.post(new Runnable() {
					public void run() {
						settingDialog.show();
					}
				});
			}
		});

		// Set a listener to send message button
		btnSendMsg.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				if (!XmppConnection.isConnected())
					return;
				String to = mRecipient.getText().toString();
				String text = mSendText.getText().toString();
				mSendText.setText("");

				if (text == null) {
					text = "Demo";
				}

				Log.i("XMPPClient", "Sending text [" + text + "] to [" + to
						+ "]");
				Message msg = new Message(to, Message.Type.chat);
				msg.setBody(text);
				Log.i("XMPPClient", "Before send packet");
				//connection.sendPacket(msg);
				XmppConnection.sendPacket(msg);
				Log.i("XMPPClient", "Packet sended!");
				if (userName != null){
					messages.add(userName + ": " + text);
				}
				else{
					//messages.add(connection.getUser() + ": " + text);
					messages.add(userName + ": " + text);
				}
				
//				messages.add(text);
				setListAdapter();
				Log.i("XMPPClient", "SendListener Finished!");
			}
		});		
		
		
		btnRecipient.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				mHandler.post(new Runnable() {					
					public void run() {
						friendListDlg.show();
					}
				});
			}
		});
		
		btnYourRequest.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				mHandler.post(new Runnable() {
					
					public void run() {
						requesterListDlg.show();
					}
				});
			}
		});
		
		Button btnAddFriend = (Button) findViewById(R.id.btnAddFriend);
		btnAddFriend.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				mHandler.post(new Runnable() {
					
					public void run() {
						addFriendDialog.show();
					}
				});
			}
		});
	}
	
	private void setPacketListenerFromConnection(){
		if (XmppConnection.isConnected()){
			PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
			XmppConnection.setPacketListener(new PacketListener() {
				public void processPacket(Packet packet) {
					Message msgRecieved = (Message) packet;
					if (msgRecieved.getBody() != null) {
						String fromName="init";
						if (recipient != null){
							fromName = recipient.name.trim();
						}
						else {
							fromName = StringUtils.parseBareAddress(msgRecieved
									.getFrom()).trim();
						}
						
						Log.i("XMPPClient", "Got text [" + msgRecieved.getBody()
								+ "] from [" + fromName + "]");
						messages.add(fromName + ": " + msgRecieved.getBody());
//						messages.add(message.getBody());
						// Add the incoming message to the list view
						mHandler.post(new Runnable() {
							public void run() {
								setListAdapter();
							}
						});
					}
				}
			}, filter);
		}
	}

	private void setListAdapter() {
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				R.layout.chat_multi_line_list_item, messages);
		mList.setAdapter(adapter);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		Log.i("XmppCLient", "[OnDestroy]");
//		LogOutAndCloseConnection();
	}
	
//	private void LogOutAndCloseConnection(){
//		if (connection != null){
//			connection.disconnect();
//		}
//	}
	
	private Boolean isConnectedToChatServer(String userEmail, String pwd){
		ChatServiceHelper chatHelper = new ChatServiceHelper();
		userName = chatHelper.getMyName(userEmail, pwd);
		
		return userName != null;
	}
	
	private Boolean SetUserNameToButtonSetup(String userEmail, String pwd){		
		ChatServiceHelper chatHelper = new ChatServiceHelper();
		userName = chatHelper.getMyName(userEmail, pwd);
		
		if (userName == Constants.USERNAME_NOT_AVAILABLE){	//This mean that server not connected
			Log.e("XmppClient", "[SetUserNameIfConnected] UserName is not available at server");			
			return false;
		}
		
		if (userName.length() > 0){
			userName = userName.trim();
			Log.i("XmppClient", "SetUserNameIfConnected:" + userName + " btnSetUp null? : " + (btnSetup==null) + "userName:" + userName);
			try {
				btnSetup.setText(userName);
			} catch (Exception e) {
				Log.e("XmppClient", "[SetUserNameIfConnected] exception: " + e.getMessage());
			}
		}
		return true;
	}
	
	public void setNewRecipient(UserDTO newRecipient){
		try {
			recipient = newRecipient;
			Button btnRecipient = (Button) findViewById(R.id.btnRecipient);
			btnRecipient.setText(recipient.name);
			mRecipient.setText(recipient.email);
			Log.i("XmppClient", "[setRecipientText] name: " + recipient.name);
		} catch (Exception e) {
			Log.e("XmppClient", "[setRecipientText] exception: " + e.getMessage());
		}
	}
	
	public ListView getListView(){
		return mList;
	}
	
	public void newUserCreatedCallBack(){
		SetUserNameToButtonSetup(XmppConnection.userEmail, XmppConnection.hashPwd);
	}
	
	private void processDismissSettingDialog(){
		if (!XmppConnection.isConnected())
			return;
		
		this.diableButtons();
		Boolean connectedToChatServer = isConnectedToChatServer(XmppConnection.userEmail, XmppConnection.hashPwd); 
		if (!connectedToChatServer){
			Log.e("XmppClient", "[processDismissSettingDialog] can't connect to server");
			Utils.showAlertDialog(this, R.string.title_error, R.string.server_not_found_error, Constants.NOT_AVAILABLE);
		}
		else{
			Boolean availableUser = ProcessUserConnected();
			//progressDialog.dismiss();
			if (!availableUser){
				displayNewUserDialog();
			}			
			setPacketListenerFromConnection();
		}
		
		this.enableButtons();
	}
	
	private Boolean ProcessUserConnected(){
		XmppConnection.updateAvailable(Constants.STATUS_AVAILABLE);
		Log.i("XmppClient", "[ProcessUserConnected] email:"+XmppConnection.userEmail);
		return SetUserNameToButtonSetup(XmppConnection.userEmail, XmppConnection.hashPwd);
	}
	
	private void displayNewUserDialog(){
		Log.i("XmppClient", "[createNewUser] start");
		final NewUserDialog newUserDlg = new NewUserDialog(this);
		mHandler.post(new Runnable() {					
			@Override
			public void run() {
				newUserDlg.show();
			}
		});
	}
	
	private void diableButtons(){
		btnSetup.setEnabled(false);
		btnSendMsg.setEnabled(false);
		btnYourRequest.setEnabled(false);
		btnRecipient.setEnabled(false);
	}
	
	private void enableButtons(){
		btnSetup.setEnabled(true);
		btnSendMsg.setEnabled(true);
		btnYourRequest.setEnabled(true);
		btnRecipient.setEnabled(true);
	}	
}
